/*     */ package com.zimbra.cs.service.mail;
/*     */ 
/*     */ import com.google.common.collect.Lists;
/*     */ import com.google.common.collect.Sets;
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.account.Key.DistributionListBy;
/*     */ import com.zimbra.common.localconfig.DebugConfig;
/*     */ import com.zimbra.common.mime.shim.JavaMailInternetAddress;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.soap.MailConstants;
/*     */ import com.zimbra.common.util.CharsetUtil;
/*     */ import com.zimbra.common.util.L10nUtil;
/*     */ import com.zimbra.common.util.L10nUtil.MsgKey;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.LogFactory;
/*     */ import com.zimbra.common.util.Pair;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.Domain;
/*     */ import com.zimbra.cs.account.Group;
/*     */ import com.zimbra.cs.account.MailTarget;
/*     */ import com.zimbra.cs.account.NamedEntry;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Provisioning.GroupMemberEmailAddrs;
/*     */ import com.zimbra.cs.account.ShareInfo.NotificationSender;
/*     */ import com.zimbra.cs.account.ShareInfoData;
/*     */ import com.zimbra.cs.mailbox.ACL;
/*     */ import com.zimbra.cs.mailbox.ACL.Grant;
/*     */ import com.zimbra.cs.mailbox.Folder;
/*     */ import com.zimbra.cs.mailbox.MailItem;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.MailSender;
/*     */ import com.zimbra.cs.mailbox.MailServiceException;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.MailboxManager;
/*     */ import com.zimbra.cs.mailbox.Mountpoint;
/*     */ import com.zimbra.cs.mailbox.OperationContext;
/*     */ import com.zimbra.cs.mime.Mime.FixedMimeMessage;
/*     */ import com.zimbra.cs.service.UserServlet;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import com.zimbra.cs.util.AccountUtil;
/*     */ import com.zimbra.cs.util.JMSession;
/*     */ import com.zimbra.cs.util.Zimbra;
/*     */ import com.zimbra.soap.JaxbUtil;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import com.zimbra.soap.mail.message.SendShareNotificationRequest;
/*     */ import com.zimbra.soap.mail.message.SendShareNotificationRequest.Action;
/*     */ import com.zimbra.soap.mail.type.EmailAddrInfo;
/*     */ import com.zimbra.soap.type.Id;
/*     */ import java.io.ByteArrayOutputStream;
/*     */ import java.io.IOException;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Arrays;
/*     */ import java.util.Collection;
/*     */ import java.util.Date;
/*     */ import java.util.HashSet;
/*     */ import java.util.Locale;
/*     */ import java.util.Map;
/*     */ import javax.mail.Message.RecipientType;
/*     */ import javax.mail.MessagingException;
/*     */ import javax.mail.internet.AddressException;
/*     */ import javax.mail.internet.MimeMessage;
/*     */ import javax.mail.internet.MimeMultipart;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class SendShareNotification
/*     */   extends MailDocumentHandler
/*     */ {
/*  80 */   private static final Log sLog = LogFactory.getLog(SendShareNotification.class);
/*     */   
/*  82 */   private static final String[] TARGET_ITEM_PATH = { "item", "id" };
/*     */   private static final String REVOKE = "revoke";
/*     */   
/*     */   protected String[] getProxiedIdPath(Element request) {
/*  86 */     return TARGET_ITEM_PATH;
/*     */   }
/*     */   
/*     */ 
/*     */   public Element handle(Element request, Map<String, Object> context)
/*     */     throws ServiceException
/*     */   {
/*  93 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/*  94 */     OperationContext octxt = getOperationContext(zsc, context);
/*  95 */     Account account = getRequestedAccount(zsc);
/*  96 */     Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account, false);
/*     */     
/*     */ 
/*  99 */     Collection<ShareInfoData> shareInfos = validateRequest(zsc, context, octxt, mbox, request);
/*     */     
/*     */ 
/* 102 */     Element eNotes = request.getOptionalElement("notes");
/* 103 */     SendShareNotificationRequest.Action action = SendShareNotificationRequest.Action.fromString(request.getAttribute("action", null));
/* 104 */     String notes = eNotes == null ? null : eNotes.getText();
/*     */     
/*     */     try
/*     */     {
/* 108 */       Account authAccount = getAuthenticatedAccount(zsc);
/* 109 */       Collection<ShareInfoData> sharesWithGroupGrantee = Lists.newArrayList();
/* 110 */       for (ShareInfoData sid : shareInfos)
/*     */       {
/* 112 */         if (2 == sid.getGranteeTypeCode()) {
/* 113 */           sharesWithGroupGrantee.add(sid);
/*     */         } else {
/* 115 */           sendNotificationEmail(octxt, mbox, authAccount, account, sid, notes, action, null, null);
/*     */         }
/*     */       }
/*     */       
/*     */ 
/* 120 */       sendNotificationEmailToGroupGrantees(octxt, mbox, authAccount, account, sharesWithGroupGrantee, notes, action);
/*     */     }
/*     */     catch (MessagingException e)
/*     */     {
/* 124 */       throw ServiceException.FAILURE("Messaging Exception while sending share notification message", e);
/*     */     }
/*     */     
/*     */ 
/* 128 */     return zsc.createElement(MailConstants.SEND_SHARE_NOTIFICATION_RESPONSE);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private Collection<ShareInfoData> validateRequest(ZimbraSoapContext zsc, Map<String, Object> context, OperationContext octxt, Mailbox mbox, Element request)
/*     */     throws ServiceException
/*     */   {
/* 136 */     Element eShare = request.getOptionalElement("share");
/* 137 */     if (eShare != null) {
/* 138 */       return Arrays.asList(new ShareInfoData[] { validateShareRecipient(zsc, context, octxt, mbox, eShare) });
/*     */     }
/*     */     
/* 141 */     String action = request.getAttribute("action", null);
/* 142 */     ArrayList<ShareInfoData> shareInfos = new ArrayList();
/* 143 */     SendShareNotificationRequest req = (SendShareNotificationRequest)JaxbUtil.elementToJaxb(request);
/* 144 */     ItemId iid = new ItemId(req.getItem().getId(), zsc);
/* 145 */     MailItem item = mbox.getItemById(octxt, iid.getId(), MailItem.Type.UNKNOWN);
/* 146 */     Provisioning prov = Provisioning.getInstance();
/* 147 */     Account account = getRequestedAccount(zsc);
/* 148 */     if ((item instanceof Mountpoint)) {
/* 149 */       Mountpoint mp = (Mountpoint)item;
/* 150 */       account = prov.get(Key.AccountBy.id, mp.getOwnerId());
/*     */     }
/* 152 */     for (EmailAddrInfo email : req.getEmailAddresses())
/*     */     {
/*     */ 
/*     */ 
/* 156 */       boolean guestGrantee = false;
/* 157 */       byte granteeType = 1;
/* 158 */       String granteeId = null;
/* 159 */       String granteeEmail = email.getAddress();
/* 160 */       String granteeDisplayName = null;
/*     */       try {
/* 162 */         Pair<NamedEntry, String> grantee = getGrantee(zsc, granteeType, granteeId, granteeEmail);
/* 163 */         NamedEntry entry = (NamedEntry)grantee.getFirst();
/* 164 */         if ((entry instanceof MailTarget)) {
/* 165 */           Domain domain = prov.getDomain(account);
/* 166 */           String granteeDomainName = ((MailTarget)entry).getDomainName();
/* 167 */           if ((domain.isInternalSharingCrossDomainEnabled()) || (domain.getName().equals(granteeDomainName)) || (Sets.newHashSet(domain.getInternalSharingDomain()).contains(granteeDomainName)))
/*     */           {
/*     */ 
/* 170 */             if ((entry instanceof Group)) {
/* 171 */               granteeType = 2;
/*     */             }
/* 173 */             granteeId = entry.getId();
/* 174 */             granteeDisplayName = (String)grantee.getSecond();
/*     */           } else {
/* 176 */             guestGrantee = true;
/*     */           }
/*     */         }
/*     */       } catch (ServiceException e) {
/* 180 */         if (!e.getCode().equals("mail.NO_SUCH_GRANTEE")) {
/* 181 */           throw e;
/*     */         }
/* 183 */         guestGrantee = true;
/*     */       }
/* 185 */       if (guestGrantee) {
/* 186 */         granteeType = 7;
/*     */         
/* 188 */         granteeId = granteeEmail;
/*     */       }
/* 190 */       shareInfos.add(getShareInfoData(zsc, context, account, octxt, granteeType, granteeEmail, granteeId, granteeDisplayName, item, "revoke".equals(action)));
/*     */     }
/*     */     
/*     */ 
/* 194 */     return shareInfos;
/*     */   }
/*     */   
/*     */ 
/*     */   @Deprecated
/*     */   private ShareInfoData validateShareRecipient(ZimbraSoapContext zsc, Map<String, Object> context, OperationContext octxt, Mailbox mbox, Element eShare)
/*     */     throws ServiceException
/*     */   {
/* 202 */     Provisioning prov = Provisioning.getInstance();
/*     */     
/*     */ 
/*     */ 
/*     */ 
/* 207 */     byte granteeType = ACL.stringToType(eShare.getAttribute("gt"));
/* 208 */     String granteeId = eShare.getAttribute("zid", null);
/* 209 */     String granteeName = eShare.getAttribute("d", null);
/*     */     
/*     */     String granteeDisplayName;
/*     */     String matchingId;
/*     */     String granteeEmail;
/*     */     String granteeDisplayName;
/* 215 */     if (granteeType == 7) {
/* 216 */       if (granteeName == null) {
/* 217 */         throw ServiceException.INVALID_REQUEST("must specify grantee name for guest grantee type", null);
/*     */       }
/*     */       
/*     */ 
/*     */ 
/* 222 */       String matchingId = granteeName;
/* 223 */       String granteeEmail = granteeName;
/* 224 */       granteeDisplayName = granteeEmail;
/*     */     } else {
/*     */       Pair<NamedEntry, String> grantee;
/*     */       try {
/* 228 */         grantee = getGrantee(zsc, granteeType, granteeId, granteeName);
/*     */       } catch (ServiceException e) {
/* 230 */         if (e.getCode().equals("mail.NO_SUCH_GRANTEE")) {
/* 231 */           throw ServiceException.INVALID_REQUEST("no such grantee", e);
/*     */         }
/* 233 */         throw e;
/*     */       }
/*     */       
/* 236 */       NamedEntry granteeEntry = (NamedEntry)grantee.getFirst();
/* 237 */       matchingId = granteeEntry.getId();
/* 238 */       granteeEmail = granteeEntry.getName();
/* 239 */       granteeDisplayName = (String)grantee.getSecond();
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/* 245 */     Account account = getRequestedAccount(zsc);
/* 246 */     Folder folder = getFolder(octxt, account, mbox, eShare);
/*     */     
/* 248 */     Account ownerAcct = account;
/*     */     
/*     */ 
/* 251 */     if ((folder instanceof Mountpoint)) {
/* 252 */       Mountpoint mp = (Mountpoint)folder;
/* 253 */       ownerAcct = prov.get(Key.AccountBy.id, mp.getOwnerId());
/* 254 */       folder = mp;
/*     */     }
/*     */     
/* 257 */     return getShareInfoData(zsc, context, ownerAcct, octxt, granteeType, granteeEmail, matchingId, granteeDisplayName, folder, false);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static long timestamp;
/*     */   
/*     */ 
/*     */ 
/*     */   private static String template;
/*     */   
/*     */ 
/*     */ 
/*     */   private ShareInfoData getShareInfoData(ZimbraSoapContext zsc, Map<String, Object> context, Account ownerAcct, OperationContext octxt, byte granteeType, String granteeEmail, String granteeId, String granteeDisplayName, MailItem item, boolean revoke)
/*     */     throws ServiceException
/*     */   {
/* 275 */     Mountpoint mpt = (item instanceof Mountpoint) ? (Mountpoint)item : null;
/*     */     MatchingGrant matchingGrant;
/*     */     MatchingGrant matchingGrant;
/* 278 */     if (Provisioning.onLocalServer(ownerAcct)) {
/* 279 */       matchingGrant = getMatchingGrantLocal(octxt, item, granteeType, granteeId, ownerAcct);
/*     */     } else {
/* 281 */       matchingGrant = getMatchingGrantRemote(zsc, context, granteeType, granteeId, ownerAcct, mpt == null ? item.getId() : mpt.getRemoteId());
/*     */     }
/*     */     
/*     */ 
/* 285 */     if ((!revoke) && (matchingGrant == null)) {
/* 286 */       throw ServiceException.INVALID_REQUEST("no matching grant", null);
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/* 292 */     ShareInfoData sid = new ShareInfoData();
/*     */     
/* 294 */     sid.setOwnerAcctId(ownerAcct.getId());
/* 295 */     sid.setOwnerAcctEmail(ownerAcct.getName());
/* 296 */     sid.setOwnerAcctDisplayName(ownerAcct.getDisplayName());
/*     */     
/*     */ 
/* 299 */     sid.setItemId(mpt == null ? item.getId() : mpt.getRemoteId());
/* 300 */     sid.setItemUuid(mpt == null ? item.getUuid() : mpt.getRemoteUuid());
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 309 */     String path = (item instanceof Folder) ? ((Folder)item).getPath() : item.getName();
/* 310 */     sid.setPath(path);
/* 311 */     sid.setFolderDefaultView((item instanceof Folder) ? ((Folder)item).getDefaultView() : item.getType());
/*     */     
/*     */ 
/*     */ 
/* 315 */     sid.setGranteeType(granteeType);
/* 316 */     sid.setGranteeId(granteeId);
/* 317 */     sid.setGranteeName(granteeEmail);
/* 318 */     sid.setGranteeDisplayName(granteeDisplayName);
/*     */     
/* 320 */     if (revoke) {
/* 321 */       sid.setGranteeName(granteeEmail);
/* 322 */       return sid;
/*     */     }
/*     */     
/*     */ 
/* 326 */     sid.setRights(matchingGrant.getGrantedRights());
/*     */     
/*     */ 
/* 329 */     if (granteeType == 7) {
/* 330 */       String url = UserServlet.getRestUrl(ownerAcct) + path;
/* 331 */       sid.setUrl(url);
/* 332 */       sid.setGuestPassword(matchingGrant.getPassword());
/*     */     }
/*     */     
/* 335 */     return sid; }
/*     */   
/*     */   private static class MatchingGrant { ACL.Grant mGrant;
/*     */     String mGrantee;
/*     */     String mName;
/*     */     byte mType;
/*     */     short mRights;
/*     */     String mSecret;
/*     */     
/* 344 */     MatchingGrant(ACL.Grant grant) { this.mGrant = grant; }
/*     */     
/*     */     MatchingGrant(String zimbraId, byte type, short rights)
/*     */     {
/* 348 */       this.mGrantee = zimbraId;
/* 349 */       this.mType = type;
/* 350 */       this.mRights = rights; }
/*     */     
/* 352 */     void setGranteeName(String name) { this.mName = name; }
/* 353 */     void setPassword(String password) { this.mSecret = password; }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     short getGrantedRights()
/*     */     {
/* 373 */       return this.mGrant == null ? this.mRights : this.mGrant.getGrantedRights();
/*     */     }
/*     */     
/*     */     String getPassword() {
/* 377 */       return this.mGrant == null ? this.mSecret : this.mGrant.getPassword();
/*     */     }
/*     */   }
/*     */   
/*     */   private MatchingGrant getMatchingGrantLocal(OperationContext octxt, MailItem item, byte granteeType, String granteeId, Account ownerAcct) throws ServiceException
/*     */   {
/* 383 */     if ((item instanceof Mountpoint)) {
/* 384 */       Mailbox ownerMbox = MailboxManager.getInstance().getMailboxByAccount(ownerAcct, false);
/* 385 */       if (ownerMbox == null) {
/* 386 */         throw ServiceException.FAILURE("mailbox not found for account " + ownerAcct.getId(), null);
/*     */       }
/* 388 */       item = ownerMbox.getItemById(octxt, ((Mountpoint)item).getRemoteId(), MailItem.Type.UNKNOWN);
/*     */     }
/*     */     
/* 391 */     ACL acl = item.getEffectiveACL();
/* 392 */     if (acl == null) {
/* 393 */       return null;
/*     */     }
/*     */     
/* 396 */     for (ACL.Grant grant : acl.getGrants()) {
/* 397 */       if ((grant.getGranteeType() == granteeType) && (grant.getGranteeId().equals(granteeId))) {
/* 398 */         return new MatchingGrant(grant);
/*     */       }
/*     */     }
/*     */     
/* 402 */     return null;
/*     */   }
/*     */   
/*     */ 
/*     */   private MatchingGrant getMatchingGrantRemote(ZimbraSoapContext zsc, Map<String, Object> context, byte granteeType, String granteeId, Account ownerAcct, int remoteFolderId)
/*     */     throws ServiceException
/*     */   {
/* 409 */     Element remote = fetchRemoteFolder(zsc, context, ownerAcct.getId(), remoteFolderId);
/* 410 */     Element eAcl = remote.getElement("acl");
/* 411 */     if (eAcl != null) {
/* 412 */       for (Element eGrant : eAcl.listElements("grant")) {
/*     */         try {
/* 414 */           byte gt = ACL.stringToType(eGrant.getAttribute("gt"));
/* 415 */           if (gt == granteeType)
/*     */           {
/*     */ 
/* 418 */             short rights = ACL.stringToRights(eGrant.getAttribute("perm"));
/*     */             
/* 420 */             MatchingGrant grant = null;
/*     */             
/*     */ 
/*     */ 
/* 424 */             if (gt == 7)
/*     */             {
/* 426 */               String gid = eGrant.getAttribute("d");
/* 427 */               if (gid.equals(granteeId)) {
/* 428 */                 grant = new MatchingGrant(gid, gt, rights);
/*     */                 
/* 430 */                 grant.setPassword(eGrant.getAttribute("pw", null));
/*     */               }
/* 432 */             } else if ((gt == 1) || (gt == 2))
/*     */             {
/* 434 */               String gid = eGrant.getAttribute("zid");
/* 435 */               if (gid.equals(granteeId)) {
/* 436 */                 grant = new MatchingGrant(gid, gt, rights);
/*     */                 
/* 438 */                 grant.setGranteeName(eGrant.getAttribute("d", null));
/*     */               }
/*     */             }
/* 441 */             if (grant != null) {
/* 442 */               return grant;
/*     */             }
/*     */           }
/*     */         }
/*     */         catch (ServiceException e)
/*     */         {
/* 448 */           sLog.warn("cannot parse soap response for remote grant", e);
/*     */         }
/*     */       }
/*     */     }
/* 452 */     return null;
/*     */   }
/*     */   
/*     */ 
/*     */   private Element fetchRemoteFolder(ZimbraSoapContext zsc, Map<String, Object> context, String ownerId, int remoteId)
/*     */     throws ServiceException
/*     */   {
/* 459 */     Element request = zsc.createRequestElement(MailConstants.GET_FOLDER_REQUEST);
/* 460 */     request.addElement("folder").addAttribute("l", remoteId);
/*     */     
/* 462 */     Element response = proxyRequest(request, context, ownerId);
/* 463 */     Element remote = response.getOptionalElement("folder");
/* 464 */     if (remote == null)
/* 465 */       throw ServiceException.INVALID_REQUEST("cannot mount a search or mountpoint", null);
/* 466 */     return remote;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private Pair<NamedEntry, String> getGrantee(ZimbraSoapContext zsc, byte granteeType, String granteeId, String granteeName)
/*     */     throws ServiceException
/*     */   {
/* 483 */     NamedEntry entryById = null;
/* 484 */     NamedEntry entryByName = null;
/*     */     
/* 486 */     if (granteeId != null) {
/* 487 */       entryById = FolderAction.lookupGranteeByZimbraId(granteeId, granteeType);
/* 488 */       if (entryById == null) {
/* 489 */         throw MailServiceException.NO_SUCH_GRANTEE(granteeId, null);
/*     */       }
/*     */     }
/* 492 */     if (granteeName != null) {
/*     */       try {
/* 494 */         entryByName = FolderAction.lookupGranteeByName(granteeName, granteeType, zsc);
/*     */       } catch (ServiceException se) {
/* 496 */         throw MailServiceException.NO_SUCH_GRANTEE(granteeName, null);
/*     */       }
/*     */     }
/*     */     
/* 500 */     if ((entryById == null) && (entryByName == null)) {
/* 501 */       throw MailServiceException.NO_SUCH_GRANTEE("", null);
/*     */     }
/*     */     
/* 504 */     if ((entryById != null) && (entryByName != null) && (!entryById.getId().equals(entryByName.getId())))
/*     */     {
/* 506 */       throw ServiceException.INVALID_REQUEST("grantee name does not match grantee id", null);
/*     */     }
/*     */     
/* 509 */     NamedEntry grantee = entryById != null ? entryById : entryByName;
/*     */     
/*     */     String displayName;
/* 512 */     if ((grantee instanceof Account)) {
/* 513 */       displayName = ((Account)grantee).getDisplayName(); } else { String displayName;
/* 514 */       if ((grantee instanceof Group)) {
/* 515 */         displayName = ((Group)grantee).getDisplayName();
/*     */       } else {
/* 517 */         throw ServiceException.INVALID_REQUEST("unsupported grantee type for sending share notification email", null);
/*     */       }
/*     */     }
/*     */     String displayName;
/* 521 */     return new Pair(grantee, displayName);
/*     */   }
/*     */   
/*     */   private Folder getFolder(OperationContext octxt, Account authAccount, Mailbox mbox, Element eShare) throws ServiceException
/*     */   {
/* 526 */     String folderId = eShare.getAttribute("l", null);
/* 527 */     String folderPath = eShare.getAttribute("path", null);
/*     */     
/* 529 */     if ((folderId != null) && (folderPath != null)) {
/* 530 */       throw ServiceException.INVALID_REQUEST("only one of l or path can be specified", null);
/*     */     }
/*     */     
/*     */     Folder folder;
/* 534 */     if (folderId != null) {
/*     */       try {
/* 536 */         int fid = Integer.parseInt(folderId);
/* 537 */         folder = mbox.getFolderById(octxt, fid);
/* 538 */         if (folder == null)
/* 539 */           throw MailServiceException.NO_SUCH_FOLDER(folderId);
/*     */       } catch (NumberFormatException nfe) {
/* 541 */         throw ServiceException.INVALID_REQUEST("malformed item ID: " + folderId, nfe);
/*     */       }
/*     */     } else {
/* 544 */       folder = mbox.getFolderByPath(octxt, folderPath);
/* 545 */       if (folder == null) {
/* 546 */         throw MailServiceException.NO_SUCH_FOLDER(folderPath);
/*     */       }
/*     */     }
/* 549 */     return folder;
/*     */   }
/*     */   
/*     */ 
/*     */   protected MimeMessage generateShareNotification(Account authAccount, Account ownerAccount, ShareInfoData sid, String notes, SendShareNotificationRequest.Action action, Collection<String> internlaRecipients, String externalRecipient)
/*     */     throws ServiceException, MessagingException
/*     */   {
/* 556 */     Locale locale = authAccount.getLocale();
/* 557 */     String charset = authAccount.getAttr("zimbraPrefMailDefaultCharset", "utf-8");
/*     */     
/*     */ 
/* 560 */     MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(authAccount));
/*     */     L10nUtil.MsgKey subjectKey;
/*     */     L10nUtil.MsgKey subjectKey;
/* 563 */     if (action == null) {
/* 564 */       subjectKey = L10nUtil.MsgKey.shareNotifSubject;
/*     */     } else {
/* 566 */       switch (action) {
/*     */       case edit: 
/* 568 */         subjectKey = L10nUtil.MsgKey.shareModifySubject;
/* 569 */         break;
/*     */       case revoke: 
/* 571 */         subjectKey = L10nUtil.MsgKey.shareRevokeSubject;
/* 572 */         break;
/*     */       case expire: 
/* 574 */         subjectKey = L10nUtil.MsgKey.shareExpireSubject;
/* 575 */         break;
/*     */       default: 
/* 577 */         subjectKey = L10nUtil.MsgKey.shareNotifSubject;
/*     */       }
/*     */     }
/* 580 */     String subject = L10nUtil.getMessage(subjectKey, locale, new Object[0]);
/* 581 */     String ownerAcctDisplayName = ownerAccount.getDisplayName();
/* 582 */     if (ownerAcctDisplayName == null) {
/* 583 */       ownerAcctDisplayName = ownerAccount.getName();
/*     */     }
/* 585 */     subject = subject + L10nUtil.getMessage(L10nUtil.MsgKey.sharedBySubject, locale, new Object[] { sid.getName(), ownerAcctDisplayName });
/* 586 */     mm.setSubject(subject, CharsetUtil.checkCharset(subject, charset));
/* 587 */     mm.setSentDate(new Date());
/*     */     
/*     */ 
/* 590 */     mm.setFrom(AccountUtil.getFriendlyEmailAddress(ownerAccount));
/*     */     
/*     */ 
/* 593 */     mm.setSender(AccountUtil.getFriendlyEmailAddress(authAccount));
/*     */     
/*     */ 
/* 596 */     if (internlaRecipients != null) {
/* 597 */       assert (externalRecipient == null);
/* 598 */       for (String recipient : internlaRecipients) {
/*     */         try {
/* 600 */           mm.addRecipient(Message.RecipientType.TO, new JavaMailInternetAddress(recipient));
/*     */         } catch (AddressException e) {
/* 602 */           sLog.warn("Ignoring error while sending share notification to " + recipient, e);
/*     */         }
/*     */       }
/* 605 */     } else if (externalRecipient != null) {
/* 606 */       mm.setRecipient(Message.RecipientType.TO, new JavaMailInternetAddress(externalRecipient));
/*     */     } else {
/* 608 */       String recipient = sid.getGranteeName();
/* 609 */       mm.setRecipient(Message.RecipientType.TO, new JavaMailInternetAddress(recipient));
/*     */     }
/*     */     
/* 612 */     MimeMultipart mmp = ShareInfo.NotificationSender.genNotifBody(sid, notes, locale, action, externalRecipient);
/* 613 */     mm.setContent(mmp);
/* 614 */     mm.saveChanges();
/*     */     
/* 616 */     if (sLog.isDebugEnabled()) {
/*     */       try
/*     */       {
/* 619 */         ByteArrayOutputStream buf = new ByteArrayOutputStream();
/* 620 */         mm.writeTo(buf);
/* 621 */         String mmDump = new String(buf.toByteArray());
/* 622 */         sLog.debug("********\n" + mmDump);
/*     */       } catch (MessagingException e) {
/* 624 */         sLog.debug("failed log debug share notification message", e);
/*     */       } catch (IOException e) {
/* 626 */         sLog.debug("failed log debug share notification message", e);
/*     */       }
/*     */     }
/* 629 */     return mm;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private void sendNotificationEmail(OperationContext octxt, Mailbox mbox, Account authAccount, Account ownerAccount, ShareInfoData sid, String notes, SendShareNotificationRequest.Action action, Collection<String> internalRecipients, String externalRecipient)
/*     */     throws ServiceException, MessagingException
/*     */   {
/* 640 */     MimeMessage mm = generateShareNotification(authAccount, ownerAccount, sid, notes, action, internalRecipients, externalRecipient);
/*     */     
/* 642 */     mbox.getMailSender().sendMimeMessage(octxt, mbox, Boolean.valueOf(true), mm, null, null, null, null, false);
/*     */   }
/*     */   
/*     */ 
/*     */   private void sendNotificationEmailToGroupGrantees(OperationContext octxt, Mailbox mbox, Account authAccount, Account ownerAccount, Collection<ShareInfoData> sids, String notes, SendShareNotificationRequest.Action action)
/*     */     throws ServiceException, MessagingException
/*     */   {
/* 649 */     Provisioning prov = Provisioning.getInstance();
/*     */     
/* 651 */     for (ShareInfoData sid : sids) {
/* 652 */       String granteeId = sid.getGranteeId();
/* 653 */       Group group = prov.getGroupBasic(Key.DistributionListBy.id, granteeId);
/* 654 */       if (group == null)
/*     */       {
/*     */ 
/*     */ 
/*     */ 
/* 659 */         sLog.warn("Group not found for sending share notificaiton to: " + granteeId + "(" + sid.getGranteeNotifName() + ")" + ", share notification not sent");
/*     */ 
/*     */ 
/*     */ 
/*     */       }
/*     */       else
/*     */       {
/*     */ 
/*     */ 
/* 668 */         Provisioning.GroupMemberEmailAddrs addrs = prov.getMemberAddrs(group);
/* 669 */         if (addrs.groupAddr() != null)
/*     */         {
/* 671 */           sendNotificationEmail(octxt, mbox, authAccount, ownerAccount, sid, notes, action, null, null);
/*     */         }
/*     */         else
/*     */         {
/* 675 */           if (addrs.internalAddrs() != null) {
/* 676 */             sendNotificationEmail(octxt, mbox, authAccount, ownerAccount, sid, notes, action, addrs.internalAddrs(), null);
/*     */           }
/*     */           
/*     */ 
/*     */ 
/* 681 */           Collection<String> extMembers = addrs.externalAddrs();
/* 682 */           if (extMembers != null) {
/* 683 */             if (extMembers.size() <= DebugConfig.sendGroupShareNotificationSynchronouslyThreshold)
/*     */             {
/* 685 */               sendNotificationEmailToGroupExternalMembers(octxt, mbox, authAccount, ownerAccount, sid, notes, action, extMembers);
/*     */             }
/*     */             else
/*     */             {
/* 689 */               sendNotificationEmailToGroupExternalMembersAsync(octxt, mbox, authAccount, ownerAccount, sid, notes, action, extMembers);
/*     */             }
/*     */           }
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private void sendNotificationEmailToGroupExternalMembers(OperationContext octxt, Mailbox mbox, Account authAccount, Account ownerAccount, ShareInfoData sid, String notes, SendShareNotificationRequest.Action action, Collection<String> extMembers)
/*     */   {
/* 701 */     for (String extMember : extMembers) {
/*     */       try {
/* 703 */         sendNotificationEmail(octxt, mbox, authAccount, ownerAccount, sid, notes, action, null, extMember);
/*     */       }
/*     */       catch (ServiceException e) {
/* 706 */         sLog.warn("Ignoring error while sending share notification to external group member " + extMember, e);
/*     */       } catch (MessagingException e) {
/* 708 */         sLog.warn("Ignoring error while sending share notification to external group member " + extMember, e);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private void sendNotificationEmailToGroupExternalMembersAsync(final OperationContext octxt, final Mailbox mbox, final Account authAccount, final Account ownerAccount, final ShareInfoData sid, final String notes, final SendShareNotificationRequest.Action action, final Collection<String> extMembers)
/*     */   {
/* 717 */     Runnable r = new Runnable()
/*     */     {
/*     */       public void run() {
/*     */         try {
/* 721 */           SendShareNotification.this.sendNotificationEmailToGroupExternalMembers(octxt, mbox, authAccount, ownerAccount, sid, notes, action, extMembers);
/*     */         }
/*     */         catch (OutOfMemoryError e) {
/* 724 */           Zimbra.halt("OutOfMemoryError while sending share notification to external group members", e);
/*     */         }
/*     */       }
/* 727 */     };
/* 728 */     Thread senderThread = new Thread(r, "SendShareNotification");
/* 729 */     senderThread.setDaemon(true);
/* 730 */     senderThread.start();
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/mail/SendShareNotification.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */